#include "m_list.h"
#include "m_memory.h"
#include "m_mutex.h"
#include <string.h>


Int32 MListCreate(MList *self)
{
    if (self == NULL)
    {
        return kErrCodeParamsErr;
    }

    memset(self, 0x00, sizeof(MList));

    self->list_head_.item_ = NULL;
    self->list_head_.prev_ = &self->list_head_;
    self->list_head_.next_ = &self->list_head_;
    self->iter_node_ = &self->list_head_;
    self->item_cnt_ = 0;
    self->capacity_ = 0;
    self->is_init_ = True;

    return kErrCodeSucc;
}

Int32 MListDestroy(MList *self)
{
    if (self == NULL)
    {
        return kErrCodeParamsErr;
    }

    if (self->is_init_)
    {
        void *item = NULL;

        while (item = MListPop(self))
        {
            MFree(item);
        }
    }

    self->is_init_ = False;

    return kErrCodeSucc;
}

Int32 MListSetCapacity(MList *self, Int32 capacity)
{
    if (self == NULL || capacity <= 0)
    {
        return kErrCodeParamsErr;
    }

    Int32 result = kErrCodeElse;

    if (self->is_init_)
    {
        self->capacity_ = capacity;
        result = kErrCodeSucc;
    }
    else
    {
        result = kErrCodeNotCreate;
    }

    return result;
}

Int32 MListItemCount(MList *self)
{
    if (self == NULL)
    {
        return kErrCodeParamsErr;
    }

    Int32 result = kErrCodeElse;

    if (self->is_init_)
    {
        result = self->item_cnt_;
    }
    else
    {
        result = kErrCodeNotCreate;
    }

    return result;
}

Int32 MListFind(MList *self, void *item)
{
    if (self == NULL || item == NULL)
    {
        return kErrCodeParamsErr;
    }

    Int32 result = kErrCodeElse;

    if (self->is_init_)
    {
        Int32 index = 0;

        result = kErrCodeItemNotExist;
        for (MListNode *node = self->list_head_.next_; node != &self->list_head_; node = node->next_)
        {
            if (node->item_ == item)
            {
                result = index;
                break;
            }
            index ++;
        }
    }
    else
    {
        result = kErrCodeNotCreate;
    }

    return result;
}

Int32 MListPush(MList *self, void *new_item)
{
    if (self == NULL || new_item == NULL)
    {
        return kErrCodeParamsErr;
    }

    Int32 push_result = kErrCodeElse;

    if (self->is_init_)
    {
        if (self->capacity_ > 0)
        {
            while (self->item_cnt_ >= self->capacity_)
            {
                void *pop_item = MListPop(self);

                if (pop_item != NULL)
                {
                    MFree(pop_item);
                }
                else
                {
                    break;
                }
            }
        }

        MListNode *new_node = (MListNode *)MMalloc(sizeof(MListNode));

        if (new_node != NULL)
        {
            new_node->item_ = new_item;

            new_node->prev_ = self->list_head_.prev_;
            new_node->next_ = &self->list_head_;
            self->list_head_.prev_->next_ = new_node;
            self->list_head_.prev_ = new_node;

            self->item_cnt_ ++;
            self->iter_node_ = &self->list_head_;  // 重置迭代器

            push_result = kErrCodeSucc;
        }
        else
        {
            push_result = kErrCodeMallocFail;
        }
    }
    else
    {
        push_result = kErrCodeNotCreate;
    }

    return push_result;
}

void* MListPeek(MList *self)
{
    if (self == NULL)
    {
        return NULL;
    }

    void *peek_item = NULL;

    if (self->is_init_)
    {
        if (self->item_cnt_ > 0)
        {
            peek_item = &self->list_head_.next_->item_;
        }
    }

    return peek_item;
}

void* MListPop(MList *self)
{
    if (self == NULL)
    {
        return NULL;
    }

    void *pop_item = NULL;

    if (self->is_init_)
    {
        if (self->item_cnt_ > 0)  // 有成员
        {
            MListNode *frist_node = self->list_head_.next_;

            pop_item = frist_node->item_;
            self->item_cnt_ --;
            self->iter_node_ = &self->list_head_;  // 重置迭代器

            self->list_head_.next_ = frist_node->next_;
            frist_node->next_->prev_ = &self->list_head_;
            MFree(frist_node);
        }
    }

    return pop_item;
}

Int32 MListIteratorReset(MList *self)
{
    if (self == NULL)
    {
        return kErrCodeParamsErr;
    }

    Int32 result = kErrCodeElse;

    if (self->is_init_)
    {
        self->iter_node_ = &self->list_head_;
        result = kErrCodeSucc;
    }
    else
    {
        result = kErrCodeNotCreate;
    }

    return result;
}

void* MListIteratorPrev(MList *self)
{
    if (self == NULL)
    {
        return NULL;
    }

    void* result = NULL;

    if (self->is_init_)
    {
        self->iter_node_ = self->iter_node_->prev_;
        result = self->iter_node_->item_;
    }

    return result;
}

void* MListIteratorNext(MList *self)
{
    if (self == NULL)
    {
        return NULL;
    }

    void* result = NULL;

    if (self->is_init_)
    {
        self->iter_node_ = self->iter_node_->next_;
        result = self->iter_node_->item_;
    }

    return result;
}

void* MListIteratorPop(MList *self)
{
    if (self == NULL)
    {
        return NULL;
    }

    void* result = NULL;

    if (self->is_init_)
    {
        if (self->iter_node_ != &self->list_head_)
        {
            MListNode *pop_node = self->iter_node_;

            result = pop_node->item_;
            self->item_cnt_ --;
            self->iter_node_ = self->iter_node_->next_;  // 删除完节点后，迭代器主动后移

            pop_node->prev_->next_ = pop_node->next_;
            pop_node->next_->prev_ = pop_node->prev_;
            MFree(pop_node);
        }
    }

    return result;
}
